package com.fingard.dsp.bank.directbank.cib03;

import com.fingard.common.utils.json.JSONUtils;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.bankInterface.IStatement;
import com.fingard.dsp.bank.directbank.cib03.util.Base64;
import com.fingard.dsp.bank.directbank.cib03.util.Signature;
import com.fingard.dsp.bank.reqrespobj.statement.ReqQryStatement;
import com.fingard.dsp.bank.reqrespobj.statement.RetAtsStatement;
import com.fingard.dsp.bank.reqrespobj.statement.TransState;
import com.fingard.dsp.bank.reqrespobj.statement.detail.RetAtsStatementDetail;
import com.fingard.text.StringHelper;
import com.fingard.util.DEHelper;
import sun.misc.BASE64Decoder;

import java.util.Calendar;
import java.util.HashMap;

public class CIB03Statement extends CIB03Base implements IStatement {
	@Override
	public RetAtsStatement d_Qry_Statement(ReqQryStatement p_reqQrySttm) throws Exception {
		RetAtsStatement retAts = new RetAtsStatement(p_reqQrySttm);
		retAts.writeStart();
		String tmpRespCode = "";
		String tmpRespInfo = "";
		
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_reqQrySttm.actNum, "");
			if (actItem != null) {
                HashMap<String, String> postMapParams = new HashMap<String, String>();
                postMapParams.put("version", "1.0.2");
                postMapParams.put("mchtId", actItem.merchantId);
                postMapParams.put("signType", "RSA");
                postMapParams.put("serialNo", p_reqQrySttm.reqHeader.transSeqID);
                postMapParams.put("transTime", Format.DateTime14Format.format(p_reqQrySttm.getBusDate()));
                postMapParams.put("checkType", "1");
                Calendar checkDate = Calendar.getInstance();
                checkDate.setTime(p_reqQrySttm.getBusDate());
                checkDate.add(Calendar.DAY_OF_MONTH, 1);
                postMapParams.put("checkDate", Format.Date8Format.format(checkDate.getTime()));
                postMapParams.put("mac", generateMAC(postMapParams, actItem));

                String tmpStrRet = sendDataToBank(JSONUtils.map2JSON(postMapParams), "downloadSatement");
                if (StringHelper.hasAnyChar(tmpStrRet)) {
                    if (tmpStrRet.indexOf("{") >= 0) {
                        HashMap<String, String> tmpJsonRet = JSONUtils.json2Map(tmpStrRet);

                        String tmpRetCode = tmpJsonRet.get("respCode");
                        if ("E0000".equals(tmpRetCode)) {
                            // 应答返回的加密对账文件内容
                            String encryptCheckFileContent = tmpJsonRet.get("fileContent");
                            WriteBankLogLn2("银行响应文件内容密文:\r\n" + encryptCheckFileContent);
                            byte[] decompressBytes = null;
                            // 应答返回的秘钥串
                            String aesKey = tmpJsonRet.get("aesKey");
                            if (StringHelper.hasAnyChar(aesKey)) {
                                // 用商户私钥证书对秘钥串进行解密
                                String key = Signature.decoderByCFCA(aesKey,actItem.ownKeyStorePath,actItem.ownKeyPassword);
                                WriteBankLogLn("解密后秘钥串aesKe:" + key);

                                // 用AES给文件内容解密
                                byte[] fileContent = Signature.AESDecode(encryptCheckFileContent, key);
                                // 用Base64给文件内容转码
                                byte[] b = Base64.decode(new String(fileContent, "UTF-8").toCharArray());
                                // 对文件内容进行解压缩
                                decompressBytes = DEHelper.uncompress(b);
                            } else {
                                decompressBytes = DEHelper.uncompress(new BASE64Decoder().decodeBuffer(encryptCheckFileContent));
                            }
                            String tmpFileContentRet = new String(decompressBytes, getCharset());
                            WriteBankLogLn2("银行响应对账单内容:\r\n" + tmpFileContentRet);

                            String headLine = tmpFileContentRet.split("\n")[0];
                            retAts.totalNum = headLine.split("\\|")[2];

                            if (0 == Integer.parseInt(retAts.totalNum)) {
                                retAts.writeRespCode("0");
                                retAts.writeRespInfo("本日无交易!");
                                retAts.writeEnd();
                                return retAts;
                            }

                            String fileDetailContent = tmpFileContentRet.substring(tmpFileContentRet.indexOf('\n')+1);
                            String[] fileLine = fileDetailContent.split("\n");
                            for (String eachLine : fileLine) {
                                if (eachLine == null) {
                                    continue;
                                }
                                String[] values = eachLine.split("\\|");
                                if(values.length == 7) {
                                    RetAtsStatementDetail tmpRetDetail = new RetAtsStatementDetail();
                                    tmpRetDetail.askNumber = values[0];
                                    tmpRetDetail.oppAct = values[1];
                                    tmpRetDetail.amount = values[4];
                                    tmpRetDetail.busTime = values[5];
                                    tmpRetDetail.transState = TransState.Success;
                                    retAts.writeRetDetail(tmpRetDetail);
                                } else {
                                    tmpRespCode = "-1";
                                    tmpRespInfo = "账单明细列数有误，实际为:" + values.length;
                                }
                            }
                        } else {
                            tmpRespCode = "-1";
                            tmpRespInfo = tmpJsonRet.get("respMsg");
                        }
                    } else {
                        tmpRespCode = "-1";
                        tmpRespInfo = "银行响应数据不合法";
                    }
                } else {
                    tmpRespCode = "-1";
                    tmpRespInfo = "银行响应为空";
                }

                if ("-1".equals(tmpRespCode)) {
                    retAts.writeRespCode(tmpRespCode);
                    retAts.writeRespInfo(tmpRespInfo);
                } else if (retAts.getWrittenRdCount() == 0) {
                    retAts.writeRespCode("0");
                    if (StringHelper.isNullOrEmpty(tmpRespInfo)) {
                        tmpRespInfo = "交易为空";
                    }
                    retAts.writeRespInfo(tmpRespInfo);
                } else {
                    retAts.isWritedTotalNum(retAts.totalNum);
                }
			} else {
                retAts.writeRespCode("-1");
                retAts.writeRespInfo("未找到账号[" + p_reqQrySttm.actNum + "]商户配置信息,config.xml中'actSet'节点配置有误!");
            }
		} catch (Exception ex) {
			ex.printStackTrace();
			retAts.writeRespCode("-1");
			retAts.writeRespInfo(ex.getMessage());
			WriteBankLogLn(ex);
		}
		
		retAts.writeEnd();
		return retAts;
	}
}